package com.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.domain.Issue;
import com.domain.IssueComment;
import com.domain.IssueCommentResponse;
import com.domain.UserLikeWithIssueComment;
import com.domainVO.CommentIssueVO;
import com.domainVO.CommentUserIsMeVO;
import com.domainVO.CommentUserVO;
import com.domainVO.PageInfoVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mapper.helping.IssueCommentMapper;
import com.mapper.helping.IssueCommentResponseMapper;
import com.mapper.helping.IssueMapper;
import com.mapper.helping.UserLikeWithIssueCommentMapper;
import com.mapper.living.UserDao;
import com.qiniu.common.QiniuException;
import com.service.IIssueCommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.service.living.OfficialMessageService;
import com.util.QiNiuYunUtils;
import com.util.UserUtil;
import living.com.domain.OfficialMessageType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 大忽悠
 * @since 2022年02月08日
 */
@RequiredArgsConstructor
@Service
public class IssueCommentServiceImpl extends ServiceImpl<IssueCommentMapper, IssueComment> implements IIssueCommentService {
    private final UserDao userDao;
    private final UserLikeWithIssueCommentMapper userLikeWithIssueCommentMapper;
    private final IssueCommentMapper issueCommentMapper;
    private final QiNiuYunUtils qiNiuYunUtils;
    private final IssueCommentResponseMapper issueCommentResponseMapper;
    private static final ObjectMapper objectMapper=new ObjectMapper();
    private final IssueMapper issueMapper;
    private final OfficialMessageService officialMessageService;
    /**
     * 通用评论图片和视频路径处理方法
     */
    private void commonCommentPathHandle(IssueComment comment) throws JsonProcessingException {
        if(comment.getImgs()!=null&&!comment.getImgs().equals("")&&!comment.getImgs().equals("[]")) {
            List<String> list =objectMapper.readValue(comment.getImgs(), List.class);
           list=list.stream().map(x->qiNiuYunUtils.getFilePrefix()+x).collect(Collectors.toList());
            comment.setImgPaths(list);
        }comment.setImgs(null);
        if(comment.getVideos()!=null&&!comment.getVideos().equals("")&&!comment.getVideos().equals("[]")) {
            List<String> list = objectMapper.readValue(comment.getVideos(), List.class);
            list=list.stream().map(x->qiNiuYunUtils.getFilePrefix()+x).collect(Collectors.toList());
            comment.setVideoPaths(list);
        }comment.setVideos(null);
    }


    /**
     * @param commentUserVO 是否匿名决定是否带着用户信息
     */
    private void isAnony(CommentUserVO commentUserVO) {
        IssueComment comment = commentUserVO.getIssueComment();
        if(comment.getIsAnony()==0)
        {
            commentUserVO.setUser(userDao.publishWithAttention(comment.getUserId(),UserUtil.getUserId()));
        }
    }

    private void isAnony(CommentUserIsMeVO commentUserVO) {
        IssueComment comment = commentUserVO.getIssueComment();
        if(comment.getIsAnony()==0)
        {
            commentUserVO.setUser(userDao.publishWithAttention(comment.getUserId(),UserUtil.getUserId()));
        }
    }

    /**
     * 通用过滤被隐式删除的回答
     */
    private  List<IssueComment> isDeleted(List<IssueComment> comments)
    {
        return comments.stream().filter(comment->comment.getIsDeleted()==0).collect(Collectors.toList());
    }

    /**
     * 每个评论带上当前用户是否给当前评论点赞的字段
     */
    private void isLike(List<CommentUserVO> userVOList)
    {
        userVOList.forEach(x->{
            UserLikeWithIssueComment one = userLikeWithIssueCommentMapper.selectOne(new QueryWrapper<UserLikeWithIssueComment>()
                    .eq("user_id", UserUtil.getUserId())
                    .eq("comment_id", x.getIssueComment().getId()));
            if(one!=null)
            {
                x.setIsLike(1);
            }else
            {
                x.setIsLike(0);
            }
        });
    }

    private void isLike2(List<CommentUserIsMeVO> userVOList)
    {
        userVOList.forEach(x->{
            UserLikeWithIssueComment one = userLikeWithIssueCommentMapper.selectOne(new QueryWrapper<UserLikeWithIssueComment>()
                    .eq("user_id", UserUtil.getUserId())
                    .eq("comment_id", x.getIssueComment().getId()));
            if(one!=null)
            {
                x.setIsLike(1);
            }else
            {
                x.setIsLike(0);
            }
        });
    }

    private void isLike1(List<CommentIssueVO> commentIssueVOList)
    {
        commentIssueVOList.forEach(x->{
            UserLikeWithIssueComment one = userLikeWithIssueCommentMapper.selectOne(new QueryWrapper<UserLikeWithIssueComment>()
                    .eq("user_id", UserUtil.getUserId())
                    .eq("comment_id",x.getComment().getId()));
            if(one!=null)
            {
                x.setIsLike(1);
            }else
            {
                x.setIsLike(0);
            }
        });
    }


    @Override
    public Map<String,Object> getCommentsUnderTargetIssue(Integer issue_id, Integer startPage, Integer pageSize) {
        AtomicBoolean isThrow= new AtomicBoolean(false);
        Page<IssueComment> page1 = new Page<>(startPage, pageSize);
        //1.获取当前问题下所有的评论
        Page<IssueComment> comments = page(page1, new QueryWrapper<IssueComment>()
                .eq("issue_id", issue_id).orderByDesc(Arrays.asList("like_sum","response_sum","id")));
        //过滤隐式删除
        comments.setRecords(isDeleted(comments.getRecords()));
        //2.获取每个评论对应的用户信息
        List<CommentUserVO> userVOList = comments.getRecords().stream().map(comment -> {
            try {
                commonCommentPathHandle(comment);
            } catch (JsonProcessingException e) {
                isThrow.set(true);
            }
            CommentUserVO commentUserVO = CommentUserVO.builder().issueComment(comment).build();
            isAnony(commentUserVO);
            return commentUserVO;
        }).collect(Collectors.toList());
        //增加是否喜欢字段
        isLike(userVOList);
        if(isThrow.get())
        {
            throw new IllegalArgumentException("JSON序列化异常");
        }
        return PageInfoVO.builder().autoWired(page1,userVOList);
    }

    @Override
    public CommentUserIsMeVO getTargetCommentInfoDetail(Integer comment_id) throws JsonProcessingException {
        IssueComment comment = getById(comment_id);
        Assert.isTrue(comment!=null&&comment.getIsDeleted()==0,"评论不存在");
        commonCommentPathHandle(comment);
        CommentUserIsMeVO commentUserVO = CommentUserIsMeVO.builder()
                .issueComment(comment)
                .isMe(comment.getUserId().equals(UserUtil.getUserId())?1:0).build();
        isAnony(commentUserVO);
        isLike2(Arrays.asList(commentUserVO));
        return commentUserVO;
    }

    /**
     * <P>
     *     获取我发布的所有回答,每个回答需要带着问题
     * </P>
     * @param startPage
     * @param pageSize
     * @return
     */
    @Override
    public Map<String, Object> getMyComments(Integer startPage, Integer pageSize) throws JsonProcessingException {
        Page<IssueComment> page=new Page<>(startPage,pageSize);
        List<IssueComment> issueComments = page(page,new QueryWrapper<IssueComment>().eq("user_id", UserUtil.getUserId())
                .orderByDesc(Arrays.asList("like_sum","response_sum","id"))).getRecords();
        issueComments=isDeleted(issueComments);
        List<CommentIssueVO> commentIssueVOList=new ArrayList<>();
        for (IssueComment issueComment : issueComments) {
            commonCommentPathHandle(issueComment);
            //查询出当前回答对应的问题
            Issue issue = issueMapper.selectById(issueComment.getIssueId());
            CommentIssueVO commentIssueVO = CommentIssueVO.builder().comment(issueComment).issue(issue).build();
            commentIssueVOList.add(commentIssueVO);
        }
        //封装点赞
        isLike1(commentIssueVOList);
        return PageInfoVO.builder().autoWired(page,commentIssueVOList);
    }

    /**
     * <P>
     *     获取没有通过审核的问题
     * </P>
     * @param startPage
     * @param pageSize
     * @return
     */
    @Override
    public Map<String, Object> getUnauditComment(Integer startPage, Integer pageSize) throws JsonProcessingException {
        Page<IssueComment> page=new Page<>(startPage,pageSize);
        List<IssueComment> issueComments = issueCommentMapper.selectPage(page, new QueryWrapper<IssueComment>()
                .eq("is_audited", 0).orderByDesc("id")).getRecords();
        for (IssueComment issueComment : issueComments) {
            commonCommentPathHandle(issueComment);
        }
        return PageInfoVO.builder().autoWired(page,issueComments);
    }

    @Override
    public Boolean passComment(Integer comment_id) {
        return issueCommentMapper.passComment(comment_id);
    }

    @Override
    public Boolean backLogicDel(Integer comment_id, String reason) {
        IssueComment issueComment = issueCommentMapper.selectById(comment_id);
        Assert.notNull(issueComment,"回答必须存在");
        Boolean res=issueCommentMapper.logicDelTargetComment(comment_id);
        //发送官方消息
        officialMessageService.sendOfficialMessage("您的回答已被管理员删除,原因:" + reason, null, issueComment.getUserId(),
                OfficialMessageType.PUNISH);
        return res;
    }


    /**
     *   不能重复点赞
     *   1.评论点赞总数加一
     *   2.映射表增加一条记录
     */
    @Override
    @Transactional(transactionManager = "primaryTransactionManager")
    public boolean likeTargetComment(Integer comment_id) {
        //评论必须存在
        IssueComment byId = getById(comment_id);
        Assert.isTrue(byId!=null&&byId.getIsDeleted()==0,"评论不存在");
        Integer one = userLikeWithIssueCommentMapper.selectCount(new QueryWrapper<UserLikeWithIssueComment>()
                .eq("comment_id",comment_id).eq("user_id",UserUtil.getUserId()));
        //one!=0,说明点赞过了
        Assert.isTrue(one==0,"请勿重复点赞");
        //1.总数加一
        int res=issueCommentMapper.addLikeSum(comment_id,1);
        //2.映射
        int res1 = userLikeWithIssueCommentMapper.insert(UserLikeWithIssueComment.builder().commentId(comment_id).userId(UserUtil.getUserId())
                .build());
        return res==1 && res1==1;
    }

    /**
     * 总数减一
     * 映射删除
     * 取消点赞前提是已经点过赞了
     */
    @Override
    @Transactional(transactionManager = "primaryTransactionManager")
    public boolean unLikeTargetComment(Integer comment_id) {
        //评论必须存在
        IssueComment byId = getById(comment_id);
        Assert.isTrue(byId!=null&&byId.getIsDeleted()==0,"评论不存在");
        Integer one = userLikeWithIssueCommentMapper.selectCount(new QueryWrapper<UserLikeWithIssueComment>()
                .eq("comment_id",comment_id).eq("user_id",UserUtil.getUserId()));
        //one==0,说明是取消点赞过了
        Assert.isTrue(one!=0,"请先点赞");
        //1.总数减一
        int res=issueCommentMapper.addLikeSum(comment_id,-1);
        //2.映射删除
        int res1 = userLikeWithIssueCommentMapper.delete(new QueryWrapper<UserLikeWithIssueComment>()
                .eq("comment_id",comment_id).eq("user_id",UserUtil.getUserId()));
        return res==1 && res1==1;
    }

    /**
     * 删除评论需要:
     *    删除评论和点赞对应的映射关系
     *    删除评论本身记录
     *    删除评论关联的图片和视频资源
     *    删除评论下面的子评论
     *    TODO:不完整
     */
    @Override
    @Transactional(transactionManager = "primaryTransactionManager")
    public Boolean delTargetComment(Integer comment_id) throws QiniuException, JsonProcessingException {
        IssueComment issueComment = issueCommentMapper.selectById(comment_id);
        //找出所有的子评论,进行删除
        List<Integer> son_comment_ids = issueCommentResponseMapper.selectList(new QueryWrapper<IssueCommentResponse>()
                .eq("father_comment_id", comment_id)).stream().map(son -> son.getId()).collect(Collectors.toList());
        int res3 = issueCommentResponseMapper.deleteBatchIds(son_comment_ids);
        //删除评论关联的图片资源
        String imgs = issueComment.getImgs();
        if(imgs!=null)
        {
            List<String> list = objectMapper.readValue(imgs, List.class);
            for (String imgPath : list) {
                qiNiuYunUtils.deleteFile(imgPath);
            }
        }
        String videos = issueComment.getVideos();
        if(videos!=null)
        {
            List<String> list = objectMapper.readValue(videos, List.class);
            for (String videoPath : list) {
                qiNiuYunUtils.deleteFile(videoPath);
            }
        }
        //删除评论和点赞的映射
        int res = userLikeWithIssueCommentMapper.delete(new QueryWrapper<UserLikeWithIssueComment>()
                .eq("comment_id", comment_id));
        //删除评论本身
        boolean res1 = removeById(comment_id);
        return res==1 && res1 && res3==1;
    }

    /**
     *  <P>
     *      逻辑删除指定评论
     *  </P>
     * @param comment_id
     * @return
     */
    @Override
    public Boolean logicDelTargetComment(Integer comment_id) {
        IssueComment issueComment = issueCommentMapper.selectById(comment_id);
        Assert.isTrue(issueComment.getUserId().equals(UserUtil.getUserId()),"无权删除当前回答");
        Boolean res=issueCommentMapper.logicDelTargetComment(comment_id);
        return res;
    }



    @Override
    public Boolean WeiXinDel(Integer comment_id) {
        Boolean res=issueCommentMapper.logicDelTargetComment(comment_id);
        return res;
    }


}
